package com.rockcent.wechat.service;

import com.rockcent.common.common.JsonResult;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.DateUtils;
import com.rockcent.common.utils.RBeanUtils;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.*;
import com.rockcent.mall.lib.dto.*;
import com.rockcent.mall.lib.helper.LocationHelper;
import com.rockcent.mall.lib.helper.OrderEventHelper;
import com.rockcent.mall.lib.helper.OrderHelper;
import com.rockcent.mall.lib.helper.ProductEventHelper;
import com.rockcent.mall.lib.repository.*;
import com.rockcent.service.IntegrationCashCouponWalletSrv;
import com.rockcent.wechat.controller.OrderController;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by oyhk on 2016/11/11.
 * <p>
 * 订单 service
 */
@Service
public class OrderCommitService {

    private final Logger log = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private CustomerCouponWalletRepository customerCouponWalletRepository;
    @Autowired
    private MerchantCouponRepository merchantCouponRepository;
    @Autowired
    private CouponProductsRepository couponProductsRepository;
    @Autowired
    private CustomerShoppingAddressRepository customerShoppingAddressRepository;
    @Autowired
    private MerchantCouponProductsRepository merchantCouponProductsRepository;
    @Autowired
    private LocationHelper locationHelper;
    @Autowired
    private IntegrationCouponWalletRepository integrationCouponWalletRepository;
    @Autowired
    private IntegrationCashCouponWalletRepository integrationCashCouponWalletRepository;
    @Autowired
    private MallCashCouponRepository mallCashCouponRepository;
    @Autowired
    private CustomerFundRepository customerFundRepository;
    @Autowired
    private ChannelRepository channelRepository;
    @Autowired
    private MallRepository mallRepository;
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private MerchantProductRepository merchantProductRepository;
    @Autowired
    private MarketOrderRepository marketOrderRepository;
    @Autowired
    private MerchantOrderRepository merchantOrderRepository;
    @Autowired
    private MerchantOrderItemRepository merchantOrderItemRepository;
    @Autowired
    private MerchantRepository merchantRepository;
    @Autowired
    private OrderEventHelper orderEventHelper;
    @Autowired
    private ProductEventHelper productEventHelper;
    @Autowired
    private ProductQuantityRepository productQuantityRepository;
    @Autowired
    private MerchantStoreRepository merchantStoreRepository;
    @Autowired
    private MallOrderRepository mallOrderRepository;
    @Autowired
    private ChannelProductRepository channelProductRepository;
    @Autowired
    private MallFinancialSettingsRepository mallFinancialSettingsRepository;
    @Autowired
    private IntegrationCashCouponWalletSrv integrationCashCouponWalletSrv;

    @Autowired
    private ShoppingCartRepository shoppingCartRepository;

    @Transactional(propagation = Propagation.REQUIRED)
    public void commit(BuyOrderDto buyOrderDto, CustomerDto customerDto, JsonResult jsonResult) {
        if (buyOrderDto.getBuyProductList() == null || buyOrderDto.getBuyProductList().size() == 0) {
            jsonResult.errorParam("购买产品列表 不能为空", log);
            return;
        }
        OrderCommitType orderCommitType = buyOrderDto.getBuyCommitType();
        buyOrderDto.setBuyCustomerId(customerDto.getId());
        // 购买者收货地址
        CustomerShoppingAddress customerShoppingAddress = null;
        // 检查购买产品字段
        for (int i = 0; i < buyOrderDto.getBuyProductList().size(); i++) {
            BuyProductDto buyProductDto = buyOrderDto.getBuyProductList().get(i);
//            log.info("============================>buyProductDto:{}", buyProductDto);
            if (buyProductDto.getBuyId() == null) {
                jsonResult.errorParam(String.format("第 %d 个产品数据异常,产品id 不能为空", i + 1), log);
                return;
            }
            Product product = merchantProductRepository.findOne(buyProductDto.getBuyId());

            if (product == null || buyProductDto == null) {
                jsonResult.remind("产品 id : " + buyProductDto.getBuyId() + " ,记录不存在", log);
                return;
            }
            ProductStatus productStatus = product.getStatus();
            Date dateSelling = product.getDateSelling();
            if (productStatus != null && ProductStatus.SELLING == productStatus && dateSelling != null) {
                Date today = DateUtils.getCurrentDate();
                if (dateSelling.compareTo(today) == 1) {
                    jsonResult.errorParam("产品在预售中", log);
                    return;
                }
            }
            if (buyProductDto.getBuyCount() == null) {
                jsonResult.errorParam(String.format("第 %d 个产品数据异常,购买数量 不能为空", i + 1), log);
                return;
            }

            if (buyProductDto.getBuyShippingType() == null && product.getType() == ProductType.GOODS) {
                jsonResult.errorParam(String.format("第 %d 个产品数据异常,配送方式 不能为空", i + 1), log);
                return;
            }

            if (buyProductDto.getBuyShippingType() == ProductShippingType.SHOP_PICKUP && product.getShippingType() == ProductShippingType.SHIPPING) {
                jsonResult.errorParam(String.format("第 %d 个产品为物流配送，购买的配送方式错误", i + 1), log);
                return;
            }

            if (buyProductDto.getBuyShippingType() == ProductShippingType.SHOP_PICKUP && product.getType() == ProductType.GOODS) {
                if (buyProductDto.getBuyMerchantStoreId() == null) {
                    jsonResult.errorParam(String.format("第 %d 个产品数据异常,配送方式为到店自提时,门店id 不能为空", i + 1), log);
                    return;
                }
            }
            if (product.getMarketId() != null) {
                Product supplierProduct = merchantProductRepository.findByIdAndIsDelete(product.getMarketId(), Whether.NO);
                if (supplierProduct == null) {
                    jsonResult.remind(String.format("第 %d 个供应商产品,记录不存在", i + 1), log);
                    return;
                }
                if (buyProductDto.getBuyShippingType() == ProductShippingType.SHOP_PICKUP && product.getType() == ProductType.GOODS) {
                    MerchantStore supplierMerchantStore = merchantStoreRepository.findByIdAndMerchantIdAndMallIdAndIsDelete(buyProductDto.getBuyMerchantStoreId(), supplierProduct.getMerchantId(), supplierProduct.getMallId(), Whether.NO);
                    if (supplierMerchantStore == null) {
                        jsonResult.remind(String.format("第 %d 个分销产品供应商,门店记录不存在", i + 1), log);
                        return;
                    }
                }
            }
            if (buyProductDto.getBuyShippingType() == ProductShippingType.SHIPPING && product.getShippingType() == ProductShippingType.SHOP_PICKUP && product.getType() == ProductType.GOODS) {
                jsonResult.remind(String.format("第 %d 个产品配送方式为到店自提，不能选择物流配送", i + 1), log);
                return;
            }

            if (buyProductDto.getBuyShippingType() == ProductShippingType.SHIPPING) {

                if (buyOrderDto.getBuyCustomerShoppingId() == null) {
                    jsonResult.remind(String.format("第 %d 个产品是物流，收货地址 id 不能为空", i + 1), log);
                    return;
                }
                // 收货地址
                customerShoppingAddress = customerShoppingAddressRepository.findByIdAndCustomerId(buyOrderDto.getBuyCustomerShoppingId(), customerDto.getId());
                if (customerShoppingAddress == null) {
                    jsonResult.remind(String.format("第 %d 个产品是物流，收货地址 id : %d,记录不存在", i + 1, buyOrderDto.getBuyCustomerShoppingId()), log);
                    return;
                }
            }


            List<String> ignoreFieldList = new ArrayList<>();
            if (buyOrderDto.getBuyCommitType() == OrderCommitType.GIFT_PACKET) {
                ignoreFieldList.add("shareFee");
                ignoreFieldList.add("sellPrice");
            }

            ProductQuantity productQuantity = productQuantityRepository.findOne(product.getProductQuantityId());
            buyProductDto.setQuantity(productQuantity.getQuantity());
            // 以上检验通过,把所有关于产品的属性copy一次
            RBeanUtils.copyProperties(product, buyProductDto, ignoreFieldList, false);
        }
        // 购买产品 List 数据整合, 自营产品marketId 为空,设置为零
        List<BuyProductDto> buyProductDtoList = buyOrderDto.getBuyProductList().stream().map(buyProductDto -> {
            if (buyProductDto.getMarketId() == null) {
                buyProductDto.setMarketId(0L);
            }
            return buyProductDto;
        }).collect(Collectors.toList());
        // 购买产品id List
        List<Long> buyProductIdList = buyProductDtoList.stream().map(BuyProductDto::getBuyId).collect(Collectors.toList());

        Map<Long, Long> groupByByProductCount = buyProductDtoList.stream().collect(Collectors.groupingBy(BuyProductDto::getBuyId, Collectors.counting()));
        for (Map.Entry<Long, Long> entry : groupByByProductCount.entrySet()) {
            if (entry.getValue() > 1) {
                jsonResult.remind(String.format("产品 id : %d ,提交数据异常,不能同时提交两个产品id相同的json结构,请合并。", entry.getKey()), log);
                return;
            }
        }


        // 判断产品是否满足购买条件
        for (int i = 0; i < buyProductDtoList.size(); i++) {
            BuyProductDto productDto = buyProductDtoList.get(i);
            if (productDto.getQuantity() - productDto.getBuyCount() < 0) {
                jsonResult.remind("产品 id : " + productDto.getId() + " ,库存不足", log);
                return;
            }
            if (productDto.getStatus() == ProductStatus.SOLDOUT || productDto.getStatus() == ProductStatus.EXPIRED || productDto.getStatus() == ProductStatus.DELETED) {
                jsonResult.remind("产品 id : " + productDto.getId() + " ,产品状态异常", log);
                return;
            }
            // TODO: 16/10/9 限购数量 <= 之前订单购买数量 + 当前购买数量
//            if (productDto.getLimitCount() > 0 && productDto.getBuyCount() - productDto.getLimitCount() < 0) {
//                jsonResult.remind("产品 id : " + productDto.getId() + " ,不能超过限购数量", log);
//                return;
//            }

        }


        // 卡券可用产品订单项列表
        Map<Long, BuyProductCouponMerchantOrderItemDto> buyProductCouponMerchantOrderItemDtoMap = null;
        // 当有使用优惠券时
        MerchantCoupon merchantCoupon = null;
        IntegrationCouponWallet integrationCouponWallet = null;
        CustomerCouponWallet customerCouponWallet = null;

        if (buyOrderDto.getBuyIntegrationCouponId() != null && buyOrderDto.getBuyCouponWalletId() != null) {
            jsonResult.remind("不能同时使用普通卡券、积分卡券", log);
            return;
        }
        // 普通卡券
        if (buyOrderDto.getBuyCouponWalletId() != null) {
            customerCouponWallet = customerCouponWalletRepository.findByIdAndCustomerId(buyOrderDto.getBuyCouponWalletId(), customerDto.getId());
            if (customerCouponWallet == null) {
                jsonResult.remind("卡券 id : " + buyOrderDto.getBuyCouponWalletId() + " ,没有可用卡券", log);
                return;
            }

            if (customerCouponWallet.getStatus() != CustomerCouponWalletStatus.TO_USE) {
                jsonResult.remind(String.format("卡券 id : %d ,状态异常", buyOrderDto.getBuyCouponWalletId(), log), log);
                return;
            }

            // 积分卡券
            if (customerCouponWallet.getSource() == CustomerCouponWalletSource.INTEGRATION) {
                integrationCouponWallet = integrationCouponWalletRepository.findByIdAndCustomerIdAndExchangeNumAndReceiveNumAndUseNum(customerCouponWallet.getIntegrationCouponId(), customerDto.getId(), 1, 1, 0);
                if (integrationCouponWallet == null) {
                    jsonResult.remind("卡券 id : " + buyOrderDto.getBuyCouponWalletId() + " ,没有可用积分卡券", log);
                    return;
                }
            }

            merchantCoupon = merchantCouponRepository.findOne(customerCouponWallet.getCouponId());
            if (merchantCoupon == null) {
                jsonResult.remind("卡券 id : " + customerCouponWallet.getCouponId() + " ,记录不存在", log);
                return;
            }

            // 状态
            if (merchantCoupon.getStatus() != MerchantCouponStatus.ISSUED && merchantCoupon.getStatus() != MerchantCouponStatus.SOLDOUT) {
                jsonResult.remind("卡券 id : " + buyOrderDto.getBuyCouponWalletId() + " ," + merchantCoupon.getStatus().getValue(), log);
                return;
            }
            // 有效日期
            if (new Date().after(merchantCoupon.getDateDisabled())) {
                jsonResult.remind("卡券 id : " + buyOrderDto.getBuyCouponWalletId() + " , 已超过使用期", log);
                return;
            }


            List<Long> merchantIdList = buyProductDtoList.stream().map(BuyProductDto::getMerchantId).collect(Collectors.toList());
            // 卡券没有适用商家
            if (!merchantIdList.contains(merchantCoupon.getMerchantId())) {
                jsonResult.remind("卡券 id : " + buyOrderDto.getBuyCouponWalletId() + " ,没有适用商家产品", log);
                return;
            }
            // 最低消费金额
            BigDecimal calculatedLimitAmount = OrderHelper.SINGLEONE.calculatedLimitAmount(buyProductDtoList, merchantCoupon);

            // 最低消费金额
            if (merchantCoupon.getLimitAmount().subtract(calculatedLimitAmount).doubleValue() > 0d) {// 如果大于0,证明购买的产品没有达到最低消费金额
                jsonResult.remind("卡券 id : " + buyOrderDto.getBuyCouponWalletId() + " , 没有超过最低消费金额", log);
                return;
            }

            // 适用所有产品 找出对应商家发布的优惠券
            if (merchantCoupon.getUseScope() == CouponUseScope.ALL_PRODUCT) {

                MerchantCoupon finalMerchantCoupon = merchantCoupon;
                buyProductCouponMerchantOrderItemDtoMap = buyProductDtoList.stream()
                        .filter(buyProductDto -> Objects.equals(buyProductDto.getMerchantId(), finalMerchantCoupon.getMerchantId()))
                        .map(buyProductDto -> {
                            BuyProductCouponMerchantOrderItemDto buyProductCouponMerchantOrderItemDto = new BuyProductCouponMerchantOrderItemDto();
                            buyProductCouponMerchantOrderItemDto.setProductId(buyProductDto.getBuyId());
                            return buyProductCouponMerchantOrderItemDto;
                        }).collect(Collectors.toMap(BuyProductCouponMerchantOrderItemDto::getProductId, o -> o));


            }
            // 适用部分产品 找出对应商家发布的优惠券
            else if (merchantCoupon.getUseScope() == CouponUseScope.PART_PRODUCT) {
                // 查询卡券适用的产品id列表
                List<MerchantCouponProducts> couponProductList = couponProductsRepository.findByCouponIdAndProductIdIn(merchantCoupon.getId(), buyProductIdList);
                if (couponProductList == null || couponProductList.size() == 0) {
                    jsonResult.remind("卡券 id : " + merchantCoupon.getId() + " ,没有适用产品", log);
                    return;
                }

                List<Long> couponProductIdList = couponProductList.stream().map(MerchantCouponProducts::getProductId).collect(Collectors.toList());
                buyProductCouponMerchantOrderItemDtoMap = buyProductDtoList.stream()
                        .filter(buyProductDto -> couponProductIdList.contains(buyProductDto.getBuyId()))
                        .map(buyProductDto -> {
                            BuyProductCouponMerchantOrderItemDto buyProductCouponMerchantOrderItemDto = new BuyProductCouponMerchantOrderItemDto();
                            buyProductCouponMerchantOrderItemDto.setProductId(buyProductDto.getBuyId());
                            return buyProductCouponMerchantOrderItemDto;
                        }).collect(Collectors.toMap(BuyProductCouponMerchantOrderItemDto::getProductId, o -> o));

            }


        }

        // 现金券
        MallCashCoupon mallCashCoupon = null;
        IntegrationCashCouponWallet integrationCashCouponWallet = null;
        if (buyOrderDto.getBuyIntegrationCashCouponWalletId() != null) {

            integrationCashCouponWallet = integrationCashCouponWalletRepository.findByIdAndCustomerIdAndExchangeNumAndReceiveNumAndUseNum(buyOrderDto.getBuyIntegrationCashCouponWalletId(), customerDto.getId(), 1, 1, 0);
            if (integrationCashCouponWallet == null) {
                jsonResult.remind("现金券 id : " + buyOrderDto.getBuyIntegrationCashCouponWalletId() + " ,记录不存在", log);
                return;
            }
            mallCashCoupon = mallCashCouponRepository.findByIdAndMallId(integrationCashCouponWallet.getCashCouponId(), customerDto.getMallId());
            if (mallCashCoupon == null) {
                jsonResult.remind("现金券 id : " + mallCashCoupon.getId() + " ,记录不存在", log);
                return;
            }

            //现金券修改状态
            integrationCashCouponWallet.setUseNum(1L);
            integrationCashCouponWallet.setUseDate(new Date());
            IntegrationCashCouponWallet cashCouponWallet = integrationCashCouponWalletRepository.save(integrationCashCouponWallet);
            //现金券使用完毕发消息
            try {
                Long useNum = cashCouponWallet.getUseNum();
//                log.info("integrationCashCouponWallet id:{},useNum:{}", cashCouponWallet.getId(), useNum);
                integrationCashCouponWalletSrv.findCashCouponWalletPushUseOverMsg(mallCashCoupon.getMallId(), mallCashCoupon.getId());
            } catch (Exception e) {
                log.error("push use over msg error",e);
            }
        }

        if (buyOrderDto.getBuyCouponWalletId() != null && customerCouponWallet != null) {
            // 修改用户优惠券状态
            if (merchantCoupon.getIntegration() == Whether.YES) {
                integrationCouponWallet.setUseNum(1L);
                integrationCouponWallet.setUseDate(new Date());
                integrationCouponWalletRepository.save(integrationCouponWallet);
            }
            customerCouponWallet.setStatus(CustomerCouponWalletStatus.USED);
            customerCouponWallet.setUseNum(1L);
            customerCouponWallet.setVerificationWay(OrderVerificationWay.SELF_CONFIRM);
            customerCouponWalletRepository.save(customerCouponWallet);
        }

        // 检验成功。创建订单,目前只支持单平台订单
        List<Long> count = new ArrayList<>();// 子订单数量
        MerchantCoupon finalMerchantCoupon = merchantCoupon;
        List<MerchantCouponProducts> merchantCouponProductsList = new ArrayList<>();// 卡券可用产品列表


        Mall mall = mallRepository.findOne(customerDto.getMallId());
        MallFinancialSettings mallFinancialSettings = mallFinancialSettingsRepository.findTop1ByMallIdAndIsDeleteOrderByLastUpdatedDesc(mall.getId(), Whether.NO);

        // 创建平台订单
        MallOrder mallOrder = new MallOrder();

        String mallOrderNum = OrderHelper.SINGLEONE.genMallOrderNumber(customerDto.getMallId(), buyOrderDto); // 生成订单号
        mallOrder.setMallFundId(mall.getMallFundId());
        mallOrder.setOrderNum(mallOrderNum);
        mallOrder.setCustomerId(customerDto.getId());
        mallOrder.setCustomerName(customerDto.getNickName());
        mallOrder.setMallId(customerDto.getMallId());
        OrderSource orderSource = StringUtils.isBlank(buyOrderDto.getOrderSource()) ? OrderSource.WECHAT : OrderSource.valueOf(buyOrderDto.getOrderSource());
        mallOrder.setOrderSource(orderSource);
        if (customerShoppingAddress != null) {
            LocationDto locationDto = locationHelper.getFullLocation(customerShoppingAddress.getLocationId());
//          String address = locationDto.getProviceName() + locationDto.getCityName() + locationDto.getLocationName() + customerShoppingAddress.getAddress();
            String address = "";
            if(!"null".equals(locationDto.getProviceName())){
                address = address + locationDto.getProviceName();
            }
            if(!"null".equals(locationDto.getCityName())){
                address = address + locationDto.getCityName();
            }
            if(!"null".equals(locationDto.getLocationName())){
                address = address + locationDto.getLocationName();
            }
            address = address + customerShoppingAddress.getAddress();
            mallOrder.setShoppingAddress(address);
            mallOrder.setShoppingMan(customerShoppingAddress.getShoppingMan());
            mallOrder.setShoppingManPhone(customerShoppingAddress.getShoppingManPhone());
        }
        mallOrder.setRemark(buyOrderDto.getBuyRemark());
        mallOrder.setMallServiceFeeRates(mallFinancialSettings.getBusinessServiceFeeRate().toString());// 服务费率
        // 如有使用优惠卡券 并且是购物车下单
        if (finalMerchantCoupon != null && orderCommitType == OrderCommitType.COMMON) {
            mallOrder.setMerchantCouponId(finalMerchantCoupon.getId());
            // 积分卡券
            if (integrationCouponWallet != null) {
                mallOrder.setIntegrationCouponId(integrationCouponWallet.getId());
            }
            merchantCouponProductsList = merchantCouponProductsRepository.findByCouponId(finalMerchantCoupon.getId());
        }

        mallOrder.setTotalAmount(OrderHelper.SINGLEONE.calculatedMallOrderSellTotalAmount(buyProductDtoList));
        mallOrder.setDiscountTotalAmount(OrderHelper.SINGLEONE.calculatedMallOrderDiscountTotalAmount(buyProductDtoList, merchantCouponProductsList, merchantCoupon));
        mallOrder.setCouponDiscountAmount(OrderHelper.SINGLEONE.calculatedMallOrderCouponDiscountAmount(buyProductDtoList, merchantCouponProductsList, merchantCoupon));
        mallOrder.setOriTotalAmount(OrderHelper.SINGLEONE.calculatedMallOrderBaseTotalAmount(buyProductDtoList));
        mallOrder.setShareFee(buyOrderDto.getShareFee());
        mallOrder.setShareRate(buyOrderDto.getShareRate());
        mallOrder.setActualAmount(mallOrder.getDiscountTotalAmount());// 实付金额
        // 现金券
        if (mallCashCoupon != null && integrationCashCouponWallet != null) {
            mallOrder.setActualAmount(mallOrder.getActualAmount().subtract(mallCashCoupon.getFaceValue()));
            if (mallOrder.getDiscountTotalAmount().subtract(mallCashCoupon.getFaceValue()).compareTo(BigDecimal.ZERO) == -1) {
                // 当现金券大于优惠后金额，那么实付金额设置为0
                mallOrder.setActualAmount(BigDecimal.ZERO);
            }
            mallOrder.setCashCouponId(mallCashCoupon.getId());
            mallOrder.setIntegrationCashCouponId(buyOrderDto.getBuyIntegrationCashCouponWalletId());
            mallOrder.setCashCouponAmount(mallCashCoupon.getFaceValue());
            if (mallCashCoupon.getFaceValue().subtract(mallOrder.getDiscountTotalAmount()).compareTo(BigDecimal.ZERO) == 1) {
                mallOrder.setCashCouponSurplusAmount(mallCashCoupon.getFaceValue().subtract(mallOrder.getDiscountTotalAmount()));
            }

        }


        // 礼包下单
        if (orderCommitType == OrderCommitType.GIFT_PACKET) {
            mallOrder.setGiftId(buyOrderDto.getBuyGiftPacketId());
            mallOrder.setGiftName(buyOrderDto.getBuyGiftPacketName());
            mallOrder.setGiftNum(buyOrderDto.getBuyGiftPacketCount());
        }

        //推广码
        Long promotionCodeId = buyOrderDto.getBuyPromotionCodeId();
        if (promotionCodeId != null && promotionCodeId.longValue() > 0) {
            mallOrder.setPromotionCodeId(promotionCodeId);
        }

        mallOrder.setCommitType(orderCommitType);
        mallOrder = mallOrderRepository.save(mallOrder);

        MallOrder finalMallOrder = mallOrder;
        List<MerchantCouponProducts> finalMerchantCouponProductsList = merchantCouponProductsList; // 卡券可用产品列表
        // 产品按照商家分组
//        Map<Long, List<BuyProductDto>> groupByMerchantProduct = buyProductDtoList.stream().collect(Collectors.groupingBy(BuyProductDto::getMerchantId));

//        for (Long merchantId : groupByMerchantProduct.keySet()) {
//            List<BuyProductDto> merchantProductList = groupByMerchantProduct.get(merchantId);
//
//            Merchant merchant = merchantRepository.findOne(merchantId);
//            if (merchant == null) {
//                throw new APIRemindException(String.format("商家 id : %d , %s", merchantId, Merchant.REMIND_RECORD_IS_NOT_EXIST,log););
//            }
        // 按产品类型分组
        Map<ProductType, List<BuyProductDto>> groupByMerchantProductTypeMap = buyProductDtoList.stream().collect(Collectors.groupingBy(BuyProductDto::getType));


        for (ProductType productShoppingType : groupByMerchantProductTypeMap.keySet()) {
            List<BuyProductDto> productShoppingTypeList = groupByMerchantProductTypeMap.get(productShoppingType);
//            log.info("--------------------------------------->产品类型{}，对应的产品集合{}", productShoppingType, productShoppingTypeList);
        }


        for (ProductType productType : groupByMerchantProductTypeMap.keySet()) {
            List<BuyProductDto> groupByMerchantProductTypeList = groupByMerchantProductTypeMap.get(productType);

            // 产品类型:服务 拆单
            if (productType == ProductType.SERVICE) {
                // 服务订单 每一个产品都要拆成一张单

                for (BuyProductDto buyProductDto : groupByMerchantProductTypeList) {
                    // 自营订单
                    if (buyProductDto.getMarketId() == 0L) {
//                        log.info("======================>自营订单");
                        this.saveMerchantOrder(buyProductDtoList, Arrays.asList(buyProductDto), ProductShippingType.SHOP_PICKUP, finalMallOrder, buyOrderDto, finalMerchantCoupon, finalMerchantCouponProductsList, MerchantOrderMerchantRole.SELF, null, count, buyProductCouponMerchantOrderItemDtoMap);
                    } else { // 分销订单
                        this.saveMarketMerchantOrder(buyProductDtoList, buyProductDto, ProductShippingType.SHOP_PICKUP, finalMallOrder, buyOrderDto, finalMerchantCoupon, finalMerchantCouponProductsList, count, buyProductCouponMerchantOrderItemDtoMap);
                    }
                }
            }
            // 产品类型:实物 拆单
            else if (productType == ProductType.GOODS) {
//                log.info("======================>普通商品<======================");
                // 把购买产品数据归类
                Map<ProductShippingType, List<BuyProductDto>> productShoppingTypeListMap = new HashMap<>();
                productShoppingTypeListMap.put(ProductShippingType.SHIPPING, new ArrayList<>()); // 物流
                productShoppingTypeListMap.put(ProductShippingType.SHOP_PICKUP, new ArrayList<>()); // 上门自提
//                log.info("======================>按照配送方式拆单");
                Map<ProductShippingType, List<BuyProductDto>> groupByProductShoppingTypeMap = groupByMerchantProductTypeList.stream().collect(Collectors.groupingBy(BuyProductDto::getShippingType));// 配送方式分组
                // 重新包装数据、由于当产品支持上门自提、物流,拆分数据需要根据买家选择对应商品配送方式拆分
                groupByProductShoppingTypeMap.forEach((productShoppingType, productShoppingTypeList) -> {
                    if (productShoppingType == ProductShippingType.SHIPPING || productShoppingType == ProductShippingType.SHOP_PICKUP) {
                        productShoppingTypeListMap.get(productShoppingType).addAll(productShoppingTypeList);
                    }
                    // 当产品支持上门自提、物流都支持,需要另外处理
                    if (productShoppingType == ProductShippingType.SHOP_PICKUP_AND_SHIPPING) {
                        for (BuyProductDto buyProduct : productShoppingTypeList) {
                            productShoppingTypeListMap.get(buyProduct.getBuyShippingType()).add(buyProduct);
                        }
                    }
                });

                for (ProductShippingType productShoppingType : productShoppingTypeListMap.keySet()) {
                    List<BuyProductDto> productShoppingTypeList = productShoppingTypeListMap.get(productShoppingType);
//                    log.info("************************>配送方式{}，对应的产品集合{}", productShoppingType, productShoppingTypeList);
                }


                // 最终拆单方式只有, 物流、自提
                for (ProductShippingType productShoppingType : productShoppingTypeListMap.keySet()) {
                    List<BuyProductDto> productShoppingTypeList = productShoppingTypeListMap.get(productShoppingType);
//                    log.info("======================>配送方式{}，对应的产品集合{}", productShoppingType, productShoppingTypeList);
                    // 配送方式:物流类型
                    if (productShoppingType == ProductShippingType.SHIPPING) {
//                        log.info("======================>物流类型，对应的产品集合{}", productShoppingTypeList);

                        Map<Long, List<BuyProductDto>> groupByMarketIdProductMap = productShoppingTypeList.stream().collect(Collectors.groupingBy(BuyProductDto::getMarketId));
                        Map<Long, List<BuyProductDto>> groupByMarketIdProductMap2 = new HashMap<>();
                        List<BuyProductDto> notDistributProduct = new ArrayList<>();
                        for (Long marketId : groupByMarketIdProductMap.keySet()) {
                            if (marketId != 0L) {
                                notDistributProduct.addAll(groupByMarketIdProductMap.get(marketId));
                            }
                        }
                        groupByMarketIdProductMap2.put(-1L, notDistributProduct);

                        if (null != groupByMarketIdProductMap.get(0L)) {
                            groupByMarketIdProductMap2.put(0L, groupByMarketIdProductMap.get(0L));
                        }

                        for (Long marketId : groupByMarketIdProductMap2.keySet()) {
//                            log.info("======================>是否分销产品{}，对应的产品集合{}", marketId, groupByMarketIdProductMap2.get(marketId));
                        }

//                        log.info("======================>按照是否是分销产品不同拆单");
                        dealDistributeGoods(buyOrderDto, buyProductDtoList, buyProductCouponMerchantOrderItemDtoMap, count, finalMerchantCoupon, finalMallOrder, finalMerchantCouponProductsList, productShoppingType, groupByMarketIdProductMap2);

                    }
                    // 配送方式:上门自提
                    else if (productShoppingType == ProductShippingType.SHOP_PICKUP) {
                        // 按商家门店分组
                        Map<Long, List<BuyProductDto>> groupByMerchantStoreIdProductMap = productShoppingTypeList.stream().collect(Collectors.groupingBy(BuyProductDto::getBuyMerchantStoreId));

                        for (Long merchantStoreId : groupByMerchantStoreIdProductMap.keySet()) {
                            List<BuyProductDto> groupByBuyMerchantStoreIdProductList = groupByMerchantStoreIdProductMap.get(merchantStoreId);

                            Map<Long, List<BuyProductDto>> groupByMarketIdProductMap = groupByBuyMerchantStoreIdProductList.stream().collect(Collectors.groupingBy(BuyProductDto::getMarketId));

                            Map<Long, List<BuyProductDto>> groupByMarketIdProductMap2 = new HashMap<>();
                            List<BuyProductDto> notDistributProduct = new ArrayList<>();
                            for (Long marketId : groupByMarketIdProductMap.keySet()) {
                                if (marketId != 0L) {
                                    notDistributProduct.addAll(groupByMarketIdProductMap.get(marketId));
                                }
                            }
                            groupByMarketIdProductMap2.put(-1L, notDistributProduct);
                            if (null != groupByMarketIdProductMap.get(0L)) {
                                groupByMarketIdProductMap2.put(0L, groupByMarketIdProductMap.get(0L));
                            }
                            for (Long marketId : groupByMarketIdProductMap2.keySet()) {
//                                log.info("======================>是否分销产品{}，对应的产品集合{}", marketId, groupByMarketIdProductMap2.get(marketId));
                            }


//                            log.info("======================>按照是否是分销产品不同拆单");
                            dealDistributeGoods(buyOrderDto, buyProductDtoList, buyProductCouponMerchantOrderItemDtoMap, count, finalMerchantCoupon, finalMallOrder, finalMerchantCouponProductsList, productShoppingType, groupByMarketIdProductMap2);


                        }
                    }
                }
            }
        }
//        }
        // 下单成功修改库存
        for (BuyProductDto buyProductDto : buyProductDtoList) {

            // 修改产品库存
            ProductQuantity productQuantity = productQuantityRepository.findOne(buyProductDto.getProductQuantityId());
            productQuantity.setQuantity(productQuantity.getQuantity() - buyProductDto.getBuyCount());
            productQuantity.setFrozenQuantity(productQuantity.getFrozenQuantity() + buyProductDto.getBuyCount());
            productQuantityRepository.save(productQuantity);
        }

        MallOrderDto mallOrderDto = new MallOrderDto();
        mallOrderDto.setOrderNum(finalMallOrder.getOrderNum());
        mallOrderDto.setActualAmount(finalMallOrder.getActualAmount());
        mallOrderDto.setAllowPaymentMethodList(new ArrayList<>());
        CustomerFund customerFund = customerFundRepository.findByCustomerIdAndIsDelete(customerDto.getId(), Whether.NO);
//        mallOrderDto.setAllowPaymentMethodList(new ArrayList<>());
        if (mallOrderDto.getActualAmount().compareTo(BigDecimal.ZERO) == 1) {
            mallOrderDto.getAllowPaymentMethodList().add(PaymentMethod.WECHAT);
        }
        // 小程序下单只有微信支付方式
        if (!OrderSource.WXAPP.toString().equals(buyOrderDto.getOrderSource())) {
            if (customerFund.getAvailableAmount().compareTo(mallOrder.getActualAmount()) >= 0) {
                mallOrderDto.getAllowPaymentMethodList().add(PaymentMethod.BALANCE);
            }
        }
        //提交订单成功，清空购物车
        shoppingCartRepository.deleteByCustomerIdAndProductIds(customerDto.getId(), buyProductIdList);
        jsonResult.data = mallOrderDto;
    }

    private void dealDistributeGoods(BuyOrderDto buyOrderDto, List<BuyProductDto> buyProductDtoList, Map<Long, BuyProductCouponMerchantOrderItemDto> buyProductCouponMerchantOrderItemDtoMap, List<Long> count, MerchantCoupon finalMerchantCoupon, MallOrder finalMallOrder, List<MerchantCouponProducts> finalMerchantCouponProductsList, ProductShippingType productShoppingType, Map<Long, List<BuyProductDto>> groupByMarketIdProductMap2) {
        for (Long marketId : groupByMarketIdProductMap2.keySet()) {
            List<BuyProductDto> groupByMarketIdProductList = groupByMarketIdProductMap2.get(marketId);
//            log.info("======================>分销产品:{}的产品集合：{}", marketId, groupByMarketIdProductList);
            if (marketId == 0L) {
//                log.info("======================>自营的产品集合：{}", groupByMarketIdProductList);
                Map<Long, List<BuyProductDto>> groupByMerchantIdProductMap = groupByMarketIdProductList.stream().collect(Collectors.groupingBy(BuyProductDto::getMerchantId));
                for (Long groupMerchantId : groupByMerchantIdProductMap.keySet()) {
                    List<BuyProductDto> groupByMerchantIdProductList = groupByMerchantIdProductMap.get(groupMerchantId);
                    this.saveMerchantOrder(buyProductDtoList, groupByMerchantIdProductList, productShoppingType, finalMallOrder, buyOrderDto, finalMerchantCoupon, finalMerchantCouponProductsList, MerchantOrderMerchantRole.SELF, null, count, buyProductCouponMerchantOrderItemDtoMap);
                }
            } else {
                Map<Long, List<BuyProductDto>> groupByMarketMerchantIdProductMap = groupByMarketIdProductList.stream().collect(Collectors.groupingBy(BuyProductDto::getMarketMerchantId));
                for (Long marketMerchantId : groupByMarketMerchantIdProductMap.keySet()) {
                    List<BuyProductDto> groupByMarketMerchantIdProductList = groupByMarketMerchantIdProductMap.get(marketMerchantId);
//                    log.info("======================>供应商：{}的产品集合：{}", marketMerchantId, groupByMarketMerchantIdProductList);
                    Map<Long, List<BuyProductDto>> groupByMerchantIdProductMap = groupByMarketMerchantIdProductList.stream().collect(Collectors.groupingBy(BuyProductDto::getMerchantId));
                    for (Long groupMerchantId : groupByMerchantIdProductMap.keySet()) {
                        List<BuyProductDto> groupByMerchantIdProductList = groupByMerchantIdProductMap.get(groupMerchantId);
//                        log.info("======================>分销商：{}的产品集合：{}", groupMerchantId, groupByMerchantIdProductList);
                        this.saveMarketMerchantOrder(buyProductDtoList, groupByMerchantIdProductList, productShoppingType, finalMallOrder, buyOrderDto, finalMerchantCoupon, finalMerchantCouponProductsList, MerchantOrderMerchantRole.SUPPLIER, null, count, buyProductCouponMerchantOrderItemDtoMap);
                    }

                }

            }
        }
    }

    private void saveMarketMerchantOrder(List<BuyProductDto> buyProductDtoList, List<BuyProductDto> groupByMerchantIdProductList, ProductShippingType productShoppingType, MallOrder finalMallOrder, BuyOrderDto buyOrderDto, MerchantCoupon finalMerchantCoupon, List<MerchantCouponProducts> finalMerchantCouponProductsList, MerchantOrderMerchantRole supplier, Object o, List<Long> count, Map<Long, BuyProductCouponMerchantOrderItemDto> buyProductCouponMerchantOrderItemDtoMap) {
        // 供应商产品
        List<BuyProductDto> supplierProductList = new ArrayList<>();
        for (BuyProductDto distributorProduct : groupByMerchantIdProductList) {
            Product supplierProduct = merchantProductRepository.findOne(distributorProduct.getMarketId());
            BuyProductDto supplierProductDto = new BuyProductDto();
            supplierProductDto.setBuyShippingType(distributorProduct.getBuyShippingType());
            supplierProductDto.setBuyCustomerShareCode(distributorProduct.getBuyCustomerShareCode());
            supplierProductDto.setBuyChannelSalesCode(distributorProduct.getBuyChannelSalesCode());
            supplierProductDto.setBuyCount(distributorProduct.getBuyCount());
            supplierProductDto.setBuyMerchantStoreId(distributorProduct.getBuyMerchantStoreId());
            supplierProductDto.setBuyCouponId(distributorProduct.getBuyCouponId());
            supplierProductDto.setBuyId(distributorProduct.getBuyId());
            supplierProductDto.setMarketId(0L); // 供应商marketId 为0
            supplierProductDto.setBuyDistributorProductId(distributorProduct.getBuyId());
            RBeanUtils.copyProperties(supplierProduct, supplierProductDto);
            supplierProductList.add(supplierProductDto);
        }

        // 创建分销订单
        MarketOrder marketOrder = OrderHelper.SINGLEONE.packageMarketOrder(groupByMerchantIdProductList.get(0), supplierProductList.get(0), finalMallOrder);
        marketOrderRepository.save(marketOrder);

        this.saveMerchantOrder(buyProductDtoList, groupByMerchantIdProductList, productShoppingType, finalMallOrder, buyOrderDto, finalMerchantCoupon, finalMerchantCouponProductsList, MerchantOrderMerchantRole.DISTRIBUTOR, marketOrder, count, buyProductCouponMerchantOrderItemDtoMap);

        this.saveMerchantOrder(buyProductDtoList, supplierProductList, productShoppingType, finalMallOrder, buyOrderDto, finalMerchantCoupon, finalMerchantCouponProductsList, MerchantOrderMerchantRole.SUPPLIER, marketOrder, count, buyProductCouponMerchantOrderItemDtoMap);


    }


    /**
     * 保存自营订单
     *
     * @param allBuyProductDtoList       购买产品列表
     * @param merchantProductDtoList     商家订单购买产品列表
     * @param productShoppingType        产品的配送方式
     * @param mallOrder                  平台订单
     * @param buyOrderDto                订单基本信息
     * @param merchantCoupon             卡券
     * @param merchantCouponProductsList 可用卡券产品列表
     * @param count                      商家订单递增数量
     */
    private MerchantOrder saveMerchantOrder(List<BuyProductDto> allBuyProductDtoList, List<BuyProductDto> merchantProductDtoList, ProductShippingType productShoppingType, MallOrder mallOrder, BuyOrderDto buyOrderDto, MerchantCoupon merchantCoupon, List<MerchantCouponProducts> merchantCouponProductsList, MerchantOrderMerchantRole merchantOrderMerchantRole, MarketOrder marketOrder, List<Long> count, Map<Long, BuyProductCouponMerchantOrderItemDto> buyProductCouponMerchantOrderItemDtoMap) {
        MerchantOrder merchantOrder = new MerchantOrder();

        // 产品列表已经分类好,所以其中一个产品的配送类型就可以代表整个 merchantProductList 的配型类型
        BuyProductDto product = merchantProductDtoList.get(0);

        Customer customer = customerRepository.findOne(buyOrderDto.getBuyCustomerId());
        if (product.getBuyShippingType() == ProductShippingType.SHOP_PICKUP && product.getType() == ProductType.GOODS) {
            merchantOrder.setMerchantStoreId(product.getBuyMerchantStoreId());
            MerchantStore merchantStore = merchantStoreRepository.findOne(product.getBuyMerchantStoreId());
            merchantOrder.setShoppingAddress(merchantStore.getAddress() + "-" + merchantStore.getName());
            merchantOrder.setShoppingMan(customer.getNickName());
            merchantOrder.setShoppingManPhone(customer.getMobile());

        }
        if ((product.getBuyShippingType() == ProductShippingType.SHIPPING || product.getBuyShippingType() == ProductShippingType.SHOP_PICKUP_AND_SHIPPING) && product.getType() == ProductType.GOODS) {
            merchantOrder.setShoppingManPhone(mallOrder.getShoppingManPhone());
            merchantOrder.setShoppingMan(mallOrder.getShoppingMan());
            merchantOrder.setShoppingAddress(mallOrder.getShoppingAddress());
        }
        // 如果礼包下单 merchantOrder 礼包id 有值
        if (buyOrderDto.getBuyGiftPacketId() != null) {
            merchantOrder.setGiftPacketId(buyOrderDto.getBuyGiftPacketId());
        }

        merchantOrder.setMerchantRole(merchantOrderMerchantRole);
        merchantOrder.setSourceType(MerchantOrderSourceType.SELF); // 默认为自营
        if (merchantOrderMerchantRole == MerchantOrderMerchantRole.SUPPLIER || merchantOrderMerchantRole == MerchantOrderMerchantRole.DISTRIBUTOR) {
            merchantOrder.setSourceType(MerchantOrderSourceType.MARKET);
            if (marketOrder != null) {
                merchantOrder.setMarketOrderNum(marketOrder.getOrderNum());
            }
        }
        merchantOrder.setProductShoppingType(productShoppingType);
        merchantOrder.setOrderType(OrderType.valueOf(product.getType().toString()));
        merchantOrder.setStatus(OrderStatus.WAIT_PAYING);
        merchantOrder.setSettleStatus(SettlementStatus.WAIT_SETTLE);
        merchantOrder.setTotalAmount(OrderHelper.SINGLEONE.calculatedMerchantOrderSellTotalAmount(merchantProductDtoList));
        merchantOrder.setDiscountAmount(merchantOrder.getTotalAmount());
        merchantOrder.setOrderSource(mallOrder.getOrderSource());
        // 可用卡券产品总金额
        BigDecimal useCouponProductTotalAmount = BigDecimal.ZERO;
        // 可用卡券产品id列表
        List<Long> useCouponProductIdList = new ArrayList<>();
        if (merchantCoupon != null && marketOrder == null) {
            if (merchantCoupon.getUseScope() == CouponUseScope.ALL_PRODUCT) {
                useCouponProductTotalAmount = allBuyProductDtoList.stream()
                        .filter(buyProductDto -> Objects.equals(buyProductDto.getMerchantId(), merchantCoupon.getMerchantId()) && buyProductDto.getMarketId() == 0L)
                        .reduce(useCouponProductTotalAmount, (bigDecimal, buyProductDto) -> bigDecimal.add(buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount()))), BigDecimal::add);
                useCouponProductIdList = allBuyProductDtoList.stream().filter(buyProductDto -> Objects.equals(buyProductDto.getMerchantId(), merchantCoupon.getMerchantId())).map(BuyProductDto::getBuyId).collect(Collectors.toList());
            }
            if (merchantCoupon.getUseScope() == CouponUseScope.PART_PRODUCT) {
                // 卡券可用产品id列表
                List<Long> couponProductIdList = merchantCouponProductsList.stream().map(MerchantCouponProducts::getProductId).collect(Collectors.toList());
                useCouponProductTotalAmount = allBuyProductDtoList.stream()
                        .filter(buyProductDto -> couponProductIdList.contains(buyProductDto.getBuyId()) && Objects.equals(buyProductDto.getMerchantId(), merchantCoupon.getMerchantId()) && buyProductDto.getMarketId() == 0L)
                        .reduce(useCouponProductTotalAmount, (bigDecimal, buyProductDto) -> bigDecimal.add(buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount()))), BigDecimal::add);
                useCouponProductIdList = allBuyProductDtoList.stream().filter(buyProductDto -> couponProductIdList.contains(buyProductDto.getBuyId()) && Objects.equals(buyProductDto.getMerchantId(), merchantCoupon.getMerchantId())).map(BuyProductDto::getBuyId).collect(Collectors.toList());
            }
        }

        merchantOrder.setMallId(mallOrder.getMallId());
        merchantOrder.setMallOrderId(mallOrder.getId());
        merchantOrder.setMallOrderNum(mallOrder.getOrderNum());

        merchantOrder.setMerchantId(product.getMerchantId());
        merchantOrder.setMerchantName(product.getMerchantName());

        merchantOrder.setOrderNum(OrderHelper.SINGLEONE.genMerchantOrderNumber(mallOrder.getOrderNum(), count));

        merchantOrder.setRefundable(Whether.NO);
        if (product.getRefundable()) {
            merchantOrder.setRefundable(Whether.YES);
        }


        if (customer != null) {
            merchantOrder.setCustomerId(customer.getId());
            merchantOrder.setCustomerName(customer.getNickName());
        }
        merchantOrder.setRemark(buyOrderDto.getBuyRemark());
        Merchant merchant = merchantRepository.findByIdAndMallId(product.getMerchantId(), product.getMallId());
        merchantOrder.setMerchantFundId(merchant.getMerchantFundId());
        merchantOrder = merchantOrderRepository.save(merchantOrder);

        BigDecimal couponDiscountTotalAmount = BigDecimal.ZERO;

        // 如果是服务订单 merchant_order、merchant_order_item是一对一
        for (BuyProductDto buyProductDto : merchantProductDtoList) {
            MerchantOrderItem merchantOrderItem = new MerchantOrderItem();


            // 渠道分销码
            Channel defaultChannel = channelRepository.findByMerchantIdAndName(buyProductDto.getMerchantId(), Channel.DEFAULT_SELF_CHANNEL_NAME);
            if (StringUtils.isNotBlank(buyProductDto.getBuyChannelSalesCode())) {
                Channel currentChannel = channelRepository.findBySalesCodeAndIsDelete(buyProductDto.getBuyChannelSalesCode(), Whether.NO);
                if (currentChannel != null) {
                    ChannelProduct channelProduct = null;
                    // 分销产品供应商渠道码 为 分销商渠道码
                    if (merchantOrderMerchantRole == MerchantOrderMerchantRole.SUPPLIER) {
                        channelProduct = channelProductRepository.findByProductIdAndChannelIdAndIsDelete(buyProductDto.getBuyDistributorProductId(), currentChannel.getId(), Whether.NO);
                    }
                    if (merchantOrderMerchantRole == MerchantOrderMerchantRole.DISTRIBUTOR || merchantOrderMerchantRole == MerchantOrderMerchantRole.SELF) {
                        channelProduct = channelProductRepository.findByProductIdAndChannelIdAndIsDelete(buyProductDto.getBuyId(), currentChannel.getId(), Whether.NO);
                    }
                    if (channelProduct != null) {
                        defaultChannel = currentChannel;
                    } else {
//                        log.info("======================>购买产品 id : {}, 的渠道分销码无效，使用了默认渠道分销码", buyProductDto.getBuyId());
                    }
                } else {
//                    log.info("======================>购买产品 id : {}, 的渠道分销码无效，使用了默认渠道分销码", buyProductDto.getBuyId());
                }
            }
            merchantOrderItem.setChannelId(defaultChannel.getId());
            merchantOrderItem.setChannelSalesCode(defaultChannel.getSalesCode());
            merchantOrderItem.setChannelName(defaultChannel.getName());

            merchantOrderItem.setSettleStatus(SettlementStatus.WAIT_SETTLE);
            // 礼包下单
            if (buyOrderDto.getBuyGiftPacketId() != null) {
                merchantOrderItem.setGiftPacketId(buyOrderDto.getBuyGiftPacketId());
            }

            merchantOrderItem.setProductRefundable(Whether.YES);
            merchantOrderItem.setBuyCount(buyProductDto.getBuyCount());
            // 当购买产品,配送方式为上门自提时,需要设置 商家门店id
            if (buyProductDto.getBuyShippingType() == ProductShippingType.SHOP_PICKUP) {
                merchantOrderItem.setMerchantStoreId(buyProductDto.getBuyMerchantStoreId());
            }
            merchantOrderItem.setLogoUrl(buyProductDto.getLogoUrl());
            if (!buyProductDto.getRefundable()) {
                merchantOrderItem.setProductRefundable(Whether.NO);
            }


            // 订单路径
            merchantOrderItem.setPathType(MerchantOrderPathType.B2C);
            if (marketOrder != null) {
                merchantOrderItem.setPathType(MerchantOrderPathType.B2D2C);
            }

            // 分享码 && 卡券为空才能有分享返利
            String buyCustomerShareCode = buyProductDto.getBuyCustomerShareCode();
//            log.info("======================>分享码{}" + buyCustomerShareCode);
//            log.info("======================>卡券{}" + merchantCoupon);
            if (StringUtils.isNotBlank(buyCustomerShareCode) && merchantCoupon == null) {
                Customer shareCustomer = customerRepository.findByShareCode(buyCustomerShareCode);
                if (shareCustomer != null) {

                    Long isShare = null;
                    // 礼包下单
                    if (buyOrderDto.getBuyGiftPacketId() != null) {
                        isShare = mallOrderRepository.countByGiftIdAndStatusAndCustomerId(buyOrderDto.getBuyGiftPacketId(), MallOrderStatus.FINISHED, shareCustomer.getId());
                    } else {
                        if (merchantOrderMerchantRole == MerchantOrderMerchantRole.DISTRIBUTOR) {
                            isShare = merchantOrderItemRepository.countByCustomerIdAndProductId(shareCustomer.getId(), buyProductDto.getMarketId());
                        }
                        if (merchantOrderMerchantRole == MerchantOrderMerchantRole.SUPPLIER || merchantOrderMerchantRole == MerchantOrderMerchantRole.SELF) {
                            isShare = merchantOrderItemRepository.countByCustomerIdAndProductId(shareCustomer.getId(), buyProductDto.getId());
                        }
                    }
                    if (isShare != null && isShare > 0L) { // 是否购买过产品，购买过才有分享返利
                        merchantOrderItem.setSharerId(shareCustomer.getId());
                        merchantOrderItem.setSharerNickName(shareCustomer.getNickName());
                        merchantOrderItem.setShareCode(buyCustomerShareCode);

                        merchantOrderItem.setPathType(MerchantOrderPathType.B2C2C);
                        if (marketOrder != null) {
                            merchantOrderItem.setPathType(MerchantOrderPathType.B2D2C2C);
                        }
                    } else {
                        log.warn("======================>分享用户没有购买过此产品");
                    }

                } else {
                    log.warn("======================>分享码没有对应分享用户");
                }
            } else {
                log.warn("======================>分享码为空 或者 下单时使用了卡券，不能享受分享返利");
            }

            Mall mall = mallRepository.findOne(mallOrder.getMallId());
            MallFinancialSettings mallFinancialSettings = mallFinancialSettingsRepository.findTop1ByMallIdAndIsDeleteOrderByLastUpdatedDesc(mall.getId(), Whether.NO);
            merchantOrderItem.setServeRate(mallFinancialSettings.getBusinessServiceFeeRate().toString());// 服务费比率
            merchantOrderItem.setShareRate(mallFinancialSettings.getShareFeeRate() == null ? "0" : mallFinancialSettings.getShareFeeRate().toString());// 分享返利比率
            merchantOrderItem.setResellFee(BigDecimal.ZERO);
            merchantOrderItem.setShareFee(BigDecimal.ZERO);
            if (buyProductDto.getResellFee() != null) {
                merchantOrderItem.setResellFee(buyProductDto.getResellFee().multiply(new BigDecimal(buyProductDto.getBuyCount())));// 分销佣金

                if (buyOrderDto.getBuyGiftPacketId() != null && buyProductDto.getPacketResellFee() != null && buyProductDto.getMarketId() != 0) { //当为礼包时,会出现新售价,要重新计算佣金
                    merchantOrderItem.setResellFee(buyProductDto.getPacketResellFee());// 分销佣金
                }
            }
            if (buyProductDto.getShareFee() != null) {
                merchantOrderItem.setShareFee(buyProductDto.getShareFee().multiply(new BigDecimal(buyProductDto.getBuyCount())));// 默认非礼包下单 产品分享返利
                if (buyOrderDto.getBuyGiftPacketId() != null) {
                    merchantOrderItem.setShareFee(buyProductDto.getShareFee());// 礼包下单 产品分享返利
                }

            }
            if (marketOrder != null) {
                merchantOrderItem.setMarketOrderNum(marketOrder.getOrderNum());
            }

            merchantOrderItem.setCustomerId(customer.getId());
            merchantOrderItem.setCustomerName(customer.getNickName());
            merchantOrderItem.setMerchantRole(merchantOrderMerchantRole);
            merchantOrderItem.setSingleAmount(buyProductDto.getSellPrice());
            merchantOrderItem.setTotalAmount(buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount())));
            merchantOrderItem.setMerchantOrderId(merchantOrder.getId());

            merchantOrderItem.setMerchantId(merchantOrder.getMerchantId());

            merchantOrderItem.setMallOrderNum(mallOrder.getOrderNum());
            merchantOrderItem.setMerchantOrderNum(merchantOrder.getOrderNum());
            merchantOrderItem.setMallId(mallOrder.getMallId());
            merchantOrderItem.setProductId(buyProductDto.getId());
            merchantOrderItem.setProductName(buyProductDto.getName());
            merchantOrderItem.setProductDateDisabled(buyProductDto.getDateDisabled());
            merchantOrderItem.setBaseAmount(buyProductDto.getBasePrice());
            merchantOrderItem.setDiscountAmount(merchantOrderItem.getTotalAmount());
            merchantOrderItem.setCouponDiscountAmount(BigDecimal.ZERO);
//            log.info("======================>product_event记录相应事件start");
            //product_event记录相应事件
            productEventHelper.productEventSave(merchantOrder, merchantOrderItem, merchantOrderItem.getBuyCount(), ProductEventType.ORDERED);
//            log.info("======================>product_event记录相应事件end");

            // 使用优惠券
            if (merchantCoupon != null && marketOrder == null) {
//                log.info("======================>使用优惠券:");
                if (useCouponProductIdList.contains(buyProductDto.getBuyId())) {
                    BigDecimal couponDiscountAmount = BigDecimal.ZERO;


                    // 抵扣券
                    if (merchantCoupon.getType() == CouponType.VOUCHERS) {
                        BigDecimal couponDiscountAmountTotal = buyProductCouponMerchantOrderItemDtoMap
                                .entrySet().stream()
                                .filter(entry -> entry.getValue().getCouponDiscountAmount() != null)
                                .reduce(BigDecimal.ZERO, (bigDecimal, entry) -> bigDecimal.add(entry.getValue().getCouponDiscountAmount()), BigDecimal::add);

                        long remainCount = buyProductCouponMerchantOrderItemDtoMap.entrySet().stream().filter(entry -> entry.getValue().getCouponDiscountAmount() == null).count();
                        // 最后一个产品平分卡券优惠金额，卡券优惠金额 - 之前平分卡券金额
                        if (remainCount == 1L) {
                            couponDiscountAmount = merchantCoupon.getFaceValue().subtract(couponDiscountAmountTotal);
                        } else {
                            // 计算此产品优惠金额
                            if (useCouponProductTotalAmount.compareTo(BigDecimal.ZERO) > 0) {
                                couponDiscountAmount = buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount())).divide(useCouponProductTotalAmount, 10, BigDecimal.ROUND_HALF_UP).multiply(merchantCoupon.getFaceValue()).setScale(2, BigDecimal.ROUND_HALF_UP);
                            }
                        }
                    }
                    //  折扣券
                    if (merchantCoupon.getType() == CouponType.DISCOUNT) {
                        // 计算此产品折扣后金额
                        couponDiscountAmount = buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount())).subtract(buyProductDto.getSellPrice().multiply(new BigDecimal(buyProductDto.getBuyCount())).multiply(merchantCoupon.getDiscount().divide(new BigDecimal("10"), 10, BigDecimal.ROUND_HALF_UP))).setScale(2, BigDecimal.ROUND_HALF_UP);

                    }
                    couponDiscountTotalAmount = couponDiscountTotalAmount.add(couponDiscountAmount);
                    merchantOrderItem.setDiscountAmount(merchantOrderItem.getTotalAmount().subtract(couponDiscountAmount));
                    merchantOrderItem.setCouponDiscountAmount(couponDiscountAmount);
                    merchantOrderItem.setCouponId(merchantCoupon.getId());
                    buyProductCouponMerchantOrderItemDtoMap.get(buyProductDto.getBuyId()).setCouponDiscountAmount(couponDiscountAmount);
                }
            }
            merchantOrderItemRepository.save(merchantOrderItem);
        }
        merchantOrder.setCouponDiscountAmount(couponDiscountTotalAmount);
        merchantOrder.setDiscountAmount(merchantOrder.getTotalAmount().subtract(couponDiscountTotalAmount));
        merchantOrder = merchantOrderRepository.save(merchantOrder);

//        log.info("======================>订单事件start");
        // 订单事件
        orderEventHelper.saveOrderEvent(merchantOrder, OrderEventType.ORDERED, mallOrder.getCustomerName(), mallOrder.getCustomerId());
//        log.info("======================>订单事件end");

        return merchantOrder;
    }


    /**
     * 保存分销订单 产品为分销产品 每一个产品都拆分为一个订单
     *
     * @param distributorProduct  分销商产品
     * @param productShoppingType
     * @param mallOrder
     * @param buyOrderDto
     */
    private void saveMarketMerchantOrder(List<BuyProductDto> allBuyProductDtoList, BuyProductDto distributorProduct, ProductShippingType productShoppingType, MallOrder mallOrder, BuyOrderDto buyOrderDto, MerchantCoupon merchantCoupon, List<MerchantCouponProducts> merchantCouponProductsList, List<Long> count, Map<Long, BuyProductCouponMerchantOrderItemDto> buyProductCouponMerchantOrderItemDtoMap) {

        // 供应商产品
        Product supplierProduct = merchantProductRepository.findOne(distributorProduct.getMarketId());
        BuyProductDto supplierProductDto = new BuyProductDto();
        supplierProductDto.setBuyShippingType(distributorProduct.getBuyShippingType());
        supplierProductDto.setBuyCustomerShareCode(distributorProduct.getBuyCustomerShareCode());
        supplierProductDto.setBuyChannelSalesCode(distributorProduct.getBuyChannelSalesCode());
        supplierProductDto.setBuyCount(distributorProduct.getBuyCount());
        supplierProductDto.setBuyMerchantStoreId(distributorProduct.getBuyMerchantStoreId());
        supplierProductDto.setBuyCouponId(distributorProduct.getBuyCouponId());
        supplierProductDto.setBuyId(distributorProduct.getBuyId());
        supplierProductDto.setMarketId(0L); // 供应商marketId 为0
        supplierProductDto.setBuyDistributorProductId(distributorProduct.getBuyId());
        RBeanUtils.copyProperties(supplierProduct, supplierProductDto);

        // 创建分销订单
        MarketOrder marketOrder = OrderHelper.SINGLEONE.packageMarketOrder(distributorProduct, supplierProductDto, mallOrder);
        marketOrderRepository.save(marketOrder);

        // 创建分销商家订单
//        log.info("======================>创建分销商家订单");
        this.saveMerchantOrder(allBuyProductDtoList, Arrays.asList(distributorProduct), productShoppingType, mallOrder, buyOrderDto, merchantCoupon, merchantCouponProductsList, MerchantOrderMerchantRole.DISTRIBUTOR, marketOrder, count, buyProductCouponMerchantOrderItemDtoMap);

        // 创建供应商订单
//        log.info("======================>创建供应商订单");
        this.saveMerchantOrder(allBuyProductDtoList, Arrays.asList(supplierProductDto), productShoppingType, mallOrder, buyOrderDto, merchantCoupon, merchantCouponProductsList, MerchantOrderMerchantRole.SUPPLIER, marketOrder, count, buyProductCouponMerchantOrderItemDtoMap);

    }
}
